﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using VideoClipNameHelper;



//net use m: \\nedia_center\Video_AVI_Music /persistent:no
namespace Videos2Links
{
    partial class Program
    {
        private static bool IsReadDataFromDisk = true;
        private static bool IsWithoutWriting = false;
        //private static bool IsReadDataFromDisk = false;
        //private static bool IsWithoutWriting = true;
            
        private static bool IsOnlyLiked = false;

        static List<string> onlyOneTitle = new List<string>();
        static List<string> errList = new List<string>();

        static ConfigPaths cp = new ConfigPaths();

        static List<VideoFile> sourceVideoFiles;
        static List<VideoFile> sourceFilesExpanded = new List<VideoFile>();
        static List<VideoFile> altTitles = new List<VideoFile>();
        static int nErrors = 0;
        //
        static IEnumerable<IGrouping<string, VideoFile>> clipsGroupedByArtist;
        static IEnumerable<IGrouping<string, VideoFile>> clipsGroupedByArtistAlbum;
        static IEnumerable<IGrouping<string, VideoFile>> clipsGroupedByTitle;
        //
        static List<string> treeData = new List<string>();

        static void Main(string[] args)
        {
            if(args.Count() >=1)
            {
                if(0==string.Compare("IsWithoutWriting", args[0], true))
                {
                    IsWithoutWriting = true;
                }
                else if (0 == string.Compare("IsOnlyLiked", args[0], true))
                {
                    IsOnlyLiked = true;
                }
            }
            //
            //
            try
            {
                Dictionary<string, string> cDic = VideoClipNameHelper.ConfigData.ReadConfig(cp);
                //
                string key1 = "IsReadDataFromDisk".ToUpper();
                if (cDic.ContainsKey(key1))
                {
                    if (VideoClipNameHelper.ConfigData.ValueAsBool(cDic[key1])) IsReadDataFromDisk = true;
                }
                string key2 = "IsWithoutWriting".ToUpper();
                if (cDic.ContainsKey(key2))
                {
                    if (VideoClipNameHelper.ConfigData.ValueAsBool(cDic[key2])) IsWithoutWriting = true;
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("Error in {0}: {1}", ConfigData.ConfigFileName, e.Message);
                System.IO.File.WriteAllLines("errors.txt", new[] { e.Message + Environment.NewLine }, Encoding.UTF8);
                //
                return;
            }
            //
            //
            if (IsReadDataFromDisk)
            {
                nErrors += VideoClipNameHelper.VideoFile.LoadClipsFromDisk(cp.SourceDirs, ref sourceVideoFiles, errList);
                //VideoClipNameHelper.Serialization.Serialize(sourceVideoFiles);
            }
            else
            {
                nErrors += VideoClipNameHelper.Serialization.DeSerialize(ref sourceVideoFiles);
            }
            //
            //
            //================================================================
            //
            //
            //
            try
            {
                foreach (VideoFile vf in sourceVideoFiles)
                {
                    sourceFilesExpanded.Add(vf);
                    //
                    if (0 != vf.vcd.AltTitles.Count)
                    {
                        foreach(string atitle in vf.vcd.AltTitles)
                        {
                            VideoFile vf1 = new VideoFile(vf);
                            vf1.vcd.Title = atitle;
                            altTitles.Add(vf1);
                        }
                    }
                    //
                    //
                    if (vf.vcd.Artists.Count > 1)
                    {
                        foreach (string artist in vf.vcd.Artists)
                        {
                                VideoFile vf1 = new VideoFile(vf);
                                vf1.vcd.Artist = artist;
                                sourceFilesExpanded.Add(vf1);
                        }
                    }
                    //
                    //
                }
            }
            catch (Exception e)
            {
                VideoClipNameHelper.CLogger.Write("foreach (VideoFile vf in sourceVideoFiles)");
                System.Windows.Forms.MessageBox.Show(e.Message, e.InnerException.ToString(), System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error);
                return;
            }
            //
            if(IsOnlyLiked)
            {
                Console.WriteLine("-= Only Liked =-");
                byLiked();
                System.IO.File.WriteAllLines("errors.txt", errList.ToArray(), Encoding.UTF8);
                Console.WriteLine("-= END =-");
                return;
            }
            //
            treeData.Add("0|R|");
            //
            //================================================================
            //
            clipsGroupedByArtist = (from vf in sourceFilesExpanded orderby vf.vcd.Artist select vf).GroupBy(x => x.vcd.Artist.ToUpperInvariant());
            byArtist();
            //
            //================================================================
            //
            clipsGroupedByArtistAlbum = (from vf in sourceFilesExpanded where "" != vf.vcd.Album orderby vf.vcd.Artist, vf.vcd.Title select vf).GroupBy(x => x.vcd.Artist.ToUpperInvariant() + x.vcd.Album.ToUpperInvariant());
            byAlbum();
            //
            //================================================================
            //
            List<VideoFile> titles = new List<VideoFile>(sourceVideoFiles.Count + altTitles.Count);
            titles.AddRange(sourceVideoFiles);
            titles.AddRange(altTitles);
            //
            clipsGroupedByTitle = (from vf in titles orderby vf.vcd.Title select vf).GroupBy(x => x.vcd.Title.ToUpperInvariant());
            byTitle();
            //
            //================================================================
            //
            byYear();
            //
            //================================================================
            //
            byNew();
            //
            //================================================================
            //
            byLiked();
            //
            //================================================================
            //
            bySpecialFolders();
            //
            //================================================================
            //
            System.IO.File.WriteAllLines("errors.txt", errList.ToArray(), Encoding.UTF8);
            //
            treeData.Add("# -EOF-");
            System.IO.File.WriteAllLines("treeData.txt", treeData.ToArray(), Encoding.UTF8);
            //
            if (IsWithoutWriting)
            {
                Console.WriteLine("Reports");
                SaveReports(sourceFilesExpanded, clipsGroupedByArtist, clipsGroupedByTitle);
            }
            Console.WriteLine("END.");
            //
        }//Main
        //=========================================================================================================================================
        //=========================================================================================================================================
        public static void _WriteHintFile(string directory, bool valueOfRandom, params KeyValuePair<string, string>[] kv)
        {
            if (IsWithoutWriting) { return; }
            //
            string errMsg = VideoClipNameHelper.HintData.WriteHintFile(directory, valueOfRandom, kv);
            if ("" != errMsg) errList.Add(errMsg);
        }
        //=========================================================================================================================================
        public static void RecreateDirectory(string dirName)
        {
            if (IsWithoutWriting) { return; }
            //
            try {
                if (Directory.Exists(dirName))
                {
                    System.IO.Directory.Delete(dirName, true);
                }
                //
                Directory.CreateDirectory(dirName);
            }
            catch (Exception e)
            {
                string eMsg = string.Format("ERROR RecreateDirectory({0}) {1},{2}", dirName, e.Message, e.Source);
                errList.Add(eMsg);
                Console.WriteLine(eMsg);
            }

        }
        //=========================================================================================================================================
        //=========================================================================================================================================
        private static void SaveReports(List<VideoFile> sourceFilesExpanded, IEnumerable<IGrouping<string, VideoFile>> byArtist, IEnumerable<IGrouping<string, VideoFile>> byTitle)
        {
            if (!Directory.Exists(cp.ReportsDir))
            {
                Directory.CreateDirectory(cp.ReportsDir);
            }
            //=============================
            Console.WriteLine("ByArtist.txt");
            string sByArtist = "";
            foreach (var y in byArtist)
            {
                var y1 = (from x in y select x).Distinct();
                if (y1.Count() > 0)
                {
                    sByArtist += Environment.NewLine + y.Key + Environment.NewLine;
                    foreach (VideoFile vf in y1.OrderBy(x=> x.FileName()))
                    {
                        sByArtist += string.Format("\t{0}{1}", vf.FileName(), Environment.NewLine);
                    }
                }
            }
            File.WriteAllText(Path.Combine(cp.ReportsDir, "ByArtist.txt"), sByArtist, Encoding.UTF8);
            sByArtist = "";
            //
            //
            //
            //=============================
            Console.WriteLine("ByTitle-Many.txt");
            string sByTitle = "";
            foreach (var y in byTitle)
            {
                var y1 = (from x in y select x).Distinct();
                if (y1.Count() > 1)
                {
                    sByTitle += Environment.NewLine + y.Key + Environment.NewLine;
                    foreach (VideoFile vf in y1)
                    {
                        sByTitle += string.Format("\t{0}{1}", vf.FileName(), Environment.NewLine);
                    }
                }
            }
            //
            File.WriteAllText(Path.Combine(cp.ReportsDir, "ByTitle-Many.txt"), sByTitle, Encoding.UTF8);
            sByTitle = "";
            //
            //
            //
            //=============================
            Console.WriteLine("BySameTitleArtist.txt");
            string sBySameTitleArtist = "";
            /*
                        foreach (var y in byArtist)
            {
                var y1 = (from x in y select x).Distinct();
                if (y1.Count() > 0)
                {
                    sByArtist += Environment.NewLine + y.Key + Environment.NewLine;
                    foreach (VideoFile vf in y1.OrderBy(x=> x.FileName()))
                    {
                        sByArtist += string.Format("\t{0}{1}", vf.FileName(), Environment.NewLine);
                    }
                }
            }
*/
            var clipsGroupedByArtist = (from vf in sourceFilesExpanded orderby vf.vcd.Artist select vf).GroupBy(x => x.vcd.Artist.ToUpperInvariant());
            foreach (var y in clipsGroupedByArtist)
            {
                var y1 = from x in y group x by x.vcd.Title;
                //var y1 = (from x in y select x.vcd.Title).Distinct();
                foreach(var gat in y1)
                {
                    if (gat.Count() > 1)
                    {
                        sBySameTitleArtist += Environment.NewLine + y.Key + Environment.NewLine;
                        foreach (VideoFile vf in gat)
                        {
                            sBySameTitleArtist += string.Format("\t{0}{1}", vf.FileName(), Environment.NewLine);
                        }
                    }
                }
            }
            //
            File.WriteAllText(Path.Combine(cp.ReportsDir, "BySameTitleArtist.txt"), sBySameTitleArtist, Encoding.UTF8);
            sBySameTitleArtist = "";
            //
            //
            //
            //=============================
            Console.WriteLine("OnlyOneTitle.txt");
            string oot = "";
            onlyOneTitle.Sort();
            foreach (var sp in onlyOneTitle)
            {
                oot += sp + Environment.NewLine;
            }
            oot += Environment.NewLine;
            File.WriteAllText(Path.Combine(cp.ReportsDir, "OnlyOneTitle.txt"), oot, Encoding.UTF8);
            oot = "";
            //
            //
            //=============================
            Console.WriteLine("Prefixes.txt");
            List<string> pref = new List<string>();
            List<string> distinctArtists = (from x in sourceFilesExpanded select x.vcd.Artist).Distinct(StringComparer.CurrentCultureIgnoreCase).ToList();
            List<string> withoutPrefix = new List<string>();
            List<string> withPrefix = new List<string>();
            List<string> fullPostfixes = new List<string>();
            //
            foreach (string prefix in VideoClipNameHelper.CleanFileName.Prefixes)
            {
                fullPostfixes.Add(", " + prefix.TrimEnd());
            }
            //
            foreach (string artist in distinctArtists)
            {
                foreach (string postfix in fullPostfixes)
                {
                    if (artist.EndsWith(postfix, StringComparison.CurrentCultureIgnoreCase))
                    {
                        withPrefix.Add(artist);
                        goto next_artist;
                    }
                }
                withoutPrefix.Add(artist);
                next_artist:;
            }
            //
            foreach(string wop in withoutPrefix)
            {
                foreach (string postfix in fullPostfixes)
                {
                    if (withPrefix.Contains(wop + postfix, StringComparer.CurrentCultureIgnoreCase))
                    {
                        pref.Add(string.Format("{0} / {1}", wop, postfix));
                        break;
                    }
                }
            }
            //
            pref.Add("");
            File.WriteAllLines(Path.Combine(cp.ReportsDir, "Prefixes.txt"), pref.ToArray(), Encoding.UTF8);
            pref = null;
            //
            //
            //=============================
            {
                Console.WriteLine("AccentsDiffArtist.txt");
                List<string> accentsDiffArtist = new List<string>();
                //
                var cleanedArtists = (from x in sourceFilesExpanded select new { ArtistClean = RemoveAccents.DoWithoutDuplicates(x.vcd.Artist).ToUpper(), Vcd = x.vcd }).GroupBy(z => z.ArtistClean);
                foreach (var cleanedArtist in cleanedArtists)
                {
                    if (cleanedArtist.Count() < 2)
                    {
                        continue;
                    }
                    var differentArtistForm = cleanedArtist.Select(x => x.Vcd.Artist).Distinct();
                    if (differentArtistForm.Count() < 2)
                    {
                        continue;
                    }
                    accentsDiffArtist.Add(cleanedArtist.Key);
                    foreach (var dName in cleanedArtist)
                    {
                        accentsDiffArtist.Add($"\t{dName.Vcd.Artist} [{dName.Vcd.OriginalName}]");
                    }
                    accentsDiffArtist.Add("");
                    //var ccc = bb.Distinct(StringComparer.InvariantCultureIgnoreCase);
                }
                accentsDiffArtist.Add("");
                File.WriteAllLines(Path.Combine(cp.ReportsDir, "AccentsDiffArtist.txt"), accentsDiffArtist.ToArray(), Encoding.UTF8);
                accentsDiffArtist = null;
                /*
                 *             List<string> accentsDiffArtist = new List<string>();
                //
                var cleanedArtists = (from x in sourceFilesExpanded select new { ArtistClean = RemoveAccents.DoWithoutDuplicates(x.vcd.Artist).ToUpper(), Artist = x.vcd.Artist }).GroupBy(z => z.ArtistClean);
                foreach(var cleanedArtist in cleanedArtists)
                {
                    if(cleanedArtist.Count() <2)
                    {
                        continue;
                    }
                    var differentArtistForm = cleanedArtist.Select(x => x.Artist).Distinct();
                    if(differentArtistForm.Count() <2)
                    {
                        continue;
                    }
                    accentsDiffArtist.Add(cleanedArtist.Key);
                    foreach(string dName in differentArtistForm)
                    {
                        accentsDiffArtist.Add("\t" + dName);
                    }
                    accentsDiffArtist.Add("");
                    //var ccc = bb.Distinct(StringComparer.InvariantCultureIgnoreCase);
                }
                File.WriteAllLines(Path.Combine(cp.ReportsDir, "AccentsDiffArtist.txt"), accentsDiffArtist.ToArray(), Encoding.UTF8);
                accentsDiffArtist = null;

                 */
            }
            //
            //=============================
            {
                Console.WriteLine("AccentsDiffTitle.txt");
                List<string> accentsDiffTitle = new List<string>();
                //
                var cleanedTitles = (from x in sourceFilesExpanded select new { TitleClean = RemoveAccents.DoWithoutDuplicates(x.vcd.Title).ToUpper(), Vcd = x.vcd }).GroupBy(z => z.TitleClean);
                foreach (var cleanedTitle in cleanedTitles)
                {
                    if (cleanedTitle.Count() < 2)
                    {
                        continue;
                    }
                    var differentTitleForm = cleanedTitle.Select(x => x.Vcd.Title).Distinct();
                    if (differentTitleForm.Count() < 2)
                    {
                        continue;
                    }
                    accentsDiffTitle.Add(cleanedTitle.Key);
                    foreach (var dName in cleanedTitle)
                    {
                        //accentsDiffTitle.Add("\t" + dName);
                        accentsDiffTitle.Add($"\t{dName.Vcd.Title} [{dName.Vcd.OriginalName}]");
                    }
                    accentsDiffTitle.Add("");
                    //var ccc = bb.Distinct(StringComparer.InvariantCultureIgnoreCase);
                }
                accentsDiffTitle.Add("");
                File.WriteAllLines(Path.Combine(cp.ReportsDir, "AccentsDiffTitle.txt"), accentsDiffTitle.ToArray(), Encoding.UTF8);
                accentsDiffTitle = null;
                //
                //
                /*

                Console.WriteLine("AccentsDiffTitle.txt");
                List<string> accentsDiffTitle = new List<string>();
                //
                var cleanedTitles = (from x in sourceFilesExpanded select new { TitleClean = RemoveAccents.DoWithoutDuplicates(x.vcd.Title).ToUpper(), Title = x.vcd.Title }).GroupBy(z => z.TitleClean);
                foreach (var cleanedTitle in cleanedTitles)
                {
                    if (cleanedTitle.Count() < 2)
                    {
                        continue;
                    }
                    var differentTitleForm = cleanedTitle.Select(x => x.Title).Distinct();
                    if (differentTitleForm.Count() < 2)
                    {
                        continue;
                    }
                    accentsDiffTitle.Add(cleanedTitle.Key);
                    foreach (string dName in differentTitleForm)
                    {
                        accentsDiffTitle.Add("\t" + dName);
                    }
                    accentsDiffTitle.Add("");
                    //var ccc = bb.Distinct(StringComparer.InvariantCultureIgnoreCase);
                }
                File.WriteAllLines(Path.Combine(cp.ReportsDir, "AccentsDiffTitle.txt"), accentsDiffTitle.ToArray(), Encoding.UTF8);
                accentsDiffTitle = null;

                 */
            }
            //
            //=============================
            //
        }
        //=========================================================================================================================================
    }//class
    }//namespace
